﻿using Leap;
using System;
using System.Collections.Generic;

namespace GL_Core
{
    class Leaplisteners : Listener
    {
        public override void OnInit(Controller arg0)
        {
            base.OnInit(arg0);
        }

        public override void OnConnect(Controller arg0)
        {
            base.OnConnect(arg0);
        }

        public override void OnExit(Controller arg0)
        {
            base.OnExit(arg0);
        }

        public override void OnFocusLost(Controller arg0)
        {
            base.OnFocusLost(arg0);
        }

        /* waktu untuk menghandle listener, 
         * hal ini dikarenakan listener akan selalu mengupdate event */
        private long currTime;
        private long prevTime;
        private long timeTrans;

        public List<FingerPoint> fingerPoint = new List<FingerPoint>();

        public override void OnFrame(Controller arg0)
        {
            //base.OnFrame(arg0);

            /*Dapatkan nilai frame saat listener berjalan
             * */
            Frame curFrame = arg0.Frame();

            /* inisialisasi waktu sekarang dengan mengisi waktu yang ada pada frame
             * isikan timeTrans dengan perpindahan waktu antara waktu sekarang dengan sebelumnya
             */
            currTime = curFrame.Timestamp;
            timeTrans = currTime - prevTime;

            /* Inisialisasi Banyaknya jari yang aktif
             * */
            short numActiveFinger = 0;

            if (timeTrans > 100)
            {
                if (curFrame.Hands.IsEmpty.Equals(false))
                { 
                    /* Dapatkan semua jari dari jari yang terdeteksi oleh frame
                     * */
                    FingerList handFinger = curFrame.Fingers;

                    foreach (Finger finger in handFinger)
                    {
                        /* Dapatkan screen terdekat yang berpotongan dengan proyeksi dari jari */
                        Screen screen = arg0.LocatedScreens.ClosestScreenHit(finger);

                        if (screen != null && screen.IsValid.Equals(true))
                        { 
                            /*temukan jarak dari finger tip
                             * lihat referensi finger tip
                             */
                            var tipVelocity = (int)finger.TipVelocity.Magnitude;
                            /* gunakan tipVelocity untuk mereduksi variasi jitter untuk kestabilan jari
                             * ketika berada pada frame
                             * */
                            if (tipVelocity > 1)
                            { 
                                //dapatkan jari yang masuk memotong screen kedalam screen proyeksi
                                float xScrIntersect = (float)(screen.Intersect(finger, true).x);
                                float yScrIntersect = (float)(1 - screen.Intersect(finger, true).y);
                                //Console.Write("x jari pada screen: ", xScrIntersect, "y jari pada screen: ", yScrIntersect,"\n");

                                if (xScrIntersect.ToString() != "NaN")
                                {
                                    /*kirimkan posisi finger pada classfinger point,dengan cara
                                     * 1. cek banyaknya jari dengan jumlah jari aktif.
                                     * jika banyaknya jari kurang dari jumlah jari yang aktif isikan banyaknya jari tersebut
                                     * dengan posisi jari terakhir kali yang masuk pada proyeksi
                                     * jika tidak 
                                     * isikan posisi jari saat ini.
                                     * berguna untuk meneruskan posisi setiap kali posisi jari terupdate
                                     */
                                    if (fingerPoint.Count <= numActiveFinger)
                                    {
                                        fingerPoint.Add(new FingerPoint(xScrIntersect, yScrIntersect, numActiveFinger));
                                    }
                                    else
                                    {
                                        fingerPoint[numActiveFinger].g_X = xScrIntersect;
                                        fingerPoint[numActiveFinger].g_Y = yScrIntersect;
                                        fingerPoint[numActiveFinger].isActive = true;
                                    }
                                    numActiveFinger++;
                                }
                            }
                        }
                    }
                    /*cek apakah??
                     * 
                     */
                    if (numActiveFinger <= fingerPoint.Count)
                    {
                        for (int i = numActiveFinger; i < fingerPoint.Count; i++)
                        {
                            fingerPoint[i].isActive = false;
                        }
                    }

                }
                /* agar waktu selalu terupdate */
                //Console.Write("current time: ",currTime,"previous time: ",prevTime);
                prevTime = currTime;
            }
        }
    }

    class FingerPoint
    {
        public float g_X,g_Y;
        public short numFing;
        public bool isActive;

        public FingerPoint(float x,float y,short num_finger)
        {
            g_X = x;
            g_Y = y;
            isActive = true;
            numFing = num_finger;
        }
    }
}